# coding=utf-8
from django.db.models import Q
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import viewsets
from MSB_ERP.utils.pagination import GlobalPagination
from rest_framework.decorators import action
from basic_info.models import WarehouseModel
from MSB_ERP.utils.base_views import MultipleOpenMixin, MultipleDestoryMixin
from basic_info.serializer.warehouse_serializer import WarehuoseSerializer,WarehuoseSearchSerializer

class WarehousesView(viewsets.ModelViewSet, MultipleDestoryMixin, MultipleOpenMixin):
    """
           create:
           仓库信息--新增

           仓库信息新增, status: 201(成功), return: 新增仓库信息信息

           destroy:
           仓库信息--删除

           仓库信息删除, status: 204(成功), return: None

           multiple_delete:
           仓库信息--批量删除,必传参数：ids=[1,2,3,4...]

           仓库信息批量删除, status: 204(成功), return: None

           multiple_open:
           仓库信息--批量启用或者禁用,必传(json)参数：ids=[1,2,3,4...](列表中可以只有一个)，is_open=1/0

           {
               "ids":[1,2],
               "is_open":"0"
           }
           is_open=1表示禁用，is_open=0表示启用，
           仓库信息批量启用或者禁用, status: 204(成功), return: None

           update:
           仓库信息--修改,

           仓库信息修改, status: 200(成功), return: 修改后的仓库信息信息

           partial_update:
           仓库信息--局部修改,可以传参任意属性的值，服务器会修改指定的属性值

           仓库信息局部修改, status: 200(成功), return: 修改后的仓库信息信息

            find: 仓库的过滤查询

            仓库的信息列表，start：200（成功），return：仓库的信息列表

           list: 可以不要
           仓库信息--获取分页列表，可选json参数:name(名称)，mobile(手机号码)，phone(联系电话)

           {
               "name":"长沙",
               "mobile":"186"
               "phone":xxx
           }
           仓库信息列表信息, status: 200(成功), return: 仓库信息信息列表

           retrieve:
           查询某一个仓库信息

           查询指定ID的仓库信息, status: 200(成功), return: 用户仓库信息
       """

    queryset = WarehouseModel.objects.all()
    serializer_class = WarehuoseSerializer
    pagination_class = GlobalPagination

    # 判断和重写序列化的类
    def get_serializer_class(self):
        if self.action == 'find':
            return WarehuoseSearchSerializer
        else:
            return WarehuoseSerializer

    def get_queryset(self):
        # 如果请求函数是find的话
        if self.action == 'find': # 可能需要用到过滤查询
            # 接收三个可能的参数（在json中）：name，phone，moblie
            name = self.request.data.get('name',None)
            remark = self.request.data.get('remark',None)

            # 因为参数可能没有，造成过滤条件是动态的
            query = Q() # 初始化Q查询，没有条件
            if name:
                # 这里的意思是：传了哪一个参数，哪一个参数的Q查询就会进到外面的Q查询中
                # 例：如果传了name和moblie，phone没有，这样的话在外面的组合条件里面就只有name的模糊查询和moblie的模糊查询
                # 模糊查询，name like '%kwyword%'    AND后面就是对组合条件的连接
                ''' 模糊查询：输入关键字就可以查出改属性  例：name：1890000 模糊查询输入：189就可以查询到该属性 '''
                query.add(Q(name__contains =name),'AND') # 多条件组合
            if remark:
                # 模糊查询，name like '%kwyword%'
                query.add(Q(remark__contains =remark),'AND') # 多条件组合

            return WarehouseModel.objects.filter(query).all()
        else:
            return WarehouseModel.objects.all()

    json__params = openapi.Schema(type=openapi.TYPE_OBJECT, properties={
        # 参数名：接一个类型（类型一个是openapi.Schema开头的）
        # 因为他是整数，所以要openapi.TYPE_INTEGER整数类型
        'name': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_STRING),description='仓库名字的关键字'),
        'remark': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_STRING),description='仓库联系电话的关键字'),
    })

    ''' 分页的页号和每页显示的数量只能通过get请求去传参的，这是drf框架规定的，但是swagger有一个属性manual_parameters是可以支持路径传参的 '''
    # 定义分页和页号
    # openapi.Parameter 请求路径的传参 openapi.IN_QUERY请求路径中传参
    page_param = openapi.Parameter(name='page',in_=openapi.IN_QUERY,description='页号',type=openapi.TYPE_INTEGER)
    # 因为在全局变量中已经规定好了叫size了，所以参数不能变
    size_param = openapi.Parameter(name='size',in_=openapi.IN_QUERY,description='每页显示的数量',type=openapi.TYPE_INTEGER)

    ''' 在drf框架中是get请求可以通过JSON格式传参的，只是swagger文档他生成注释的时候他不支持而已，
    之前的list视图函数（get请求）的时候就是用JSON格式传参的（例：/user/?id=3） '''
    # 这个是特别的接口文档，methods表示请求的方法，request_body表示指定传参
    # 注意点位：在swagger文档中如果用get请求他是不给你使用request_body，只有在post，delete，put，patch请求中才可以使用request_body
    # request_body就是JSON格式的传参
    @swagger_auto_schema(method='post',manual_parameters=[page_param,size_param], request_body=json__params, operation_description='仓库的过滤查询')  # 装饰器一定要写在action的上面
    @action(methods=['post'], detail=False)
    def find(self,request,*args,**kwargs):
        # 用于调用父类（超类）的方法。它提供了一种方便的方式来调用父类的方法，而不需要显式地指定父类的名称。
        # list函数是父类里面的函数（他是drf框架本身的代码）
        return super(WarehousesView,self).list(request=request,*args,**kwargs)







